package pa165.dominatingspecies.service.impl;

import java.util.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import pa165.dominatingspecies.dao.impl.ElementDaoImpl;
import pa165.dominating.species.entities.Element;
import pa165.dominating.species.enums.ElementType;
import pa165.dominating.species.exceptions.ToException;
import pa165.dominating.species.service.ElementService;
import pa165.dominatingspecies.service.converter.ElementConverter;
import pa165.dominating.species.tos.ElementTo;

/**
 *
 * @author Ondrej Prazak
 */
@Service
public class ElementServiceImpl implements ElementService {

    private ElementDaoImpl elementDao;
    private ElementConverter elementConverter;

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @PreAuthorize("hasRole('ADMIN')")
    public void createElement(ElementTo elementTo) {
        nullArgumentsHelper(elementTo);
        if (elementTo.getId() != null) {
            throw new ToException("TO already has an id - cannot create");
        }
        Element ele = new Element();
        ele.setDescription(elementTo.getDescription());
        ele.setType((elementTo.getType()));

        elementDao.createElement(ele);

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @PreAuthorize("hasRole('ADMIN')")
    public void deleteElement(ElementTo elementTo) {
        if (elementTo.getId() == null) {
            throw new ToException("ElementTo ID is null - cannot delete");
        }
        nullArgumentsHelper(elementTo);
        Element ele = new Element();

        elementDao.deleteElement(elementConverter.convertElementTo2Element(elementTo));

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @PreAuthorize("hasRole('WORKER')")
    public ElementTo getElementToById(Long id) {
        if (id == null) {
            throw new ToException("id is null");
        }

        return elementConverter.convertElement2ElementTo(elementDao.getElementById(id));

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @PreAuthorize("hasRole('WORKER')")
    public List<ElementTo> getAllElementTos() {
        List<Element> found = elementDao.getAllElements();
        List<ElementTo> tos = new ArrayList<>();
        for (Element ele : found) {
            tos.add(elementConverter.convertElement2ElementTo(ele));
        }
        return tos;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @PreAuthorize("hasRole('WORKER')")
    public void updateElementTo(ElementTo elementTo) {
        nullArgumentsHelper(elementTo);
        if (elementTo.getId() == null) {
            throw new ToException("To has no id - cannot update");
        }
        elementDao.updateElement(elementConverter.convertElementTo2Element(elementTo));
    }

    @Override
    @PreAuthorize("hasRole('WORKER')")
    public ElementTo getElementToByType(ElementType type) {
        if (type == null) {
            throw new ToException("Type is null");
        }
        return elementConverter.convertElement2ElementTo(elementDao.getElementByType(type));
    }

    protected void nullArgumentsHelper(ElementTo ele) {
        if (ele == null) {
            throw new ToException("TO is null");
        }
        if (ele.getType() == null) {
            throw new ToException("TO has no type set");
        }
    }

    public ElementDaoImpl getElementDao() {
        return elementDao;
    }

    public void setElementDao(ElementDaoImpl elementDao) {
        this.elementDao = elementDao;
    }

    public ElementConverter getElementConverter() {
        return elementConverter;
    }

    public void setElementConverter(ElementConverter elementConverter) {
        this.elementConverter = elementConverter;
    }
}
